/*
 * Copyright Kulikov Victor 2009
 * Distributed under LGPL license

 * Modified by Pavel Shchelkun 2012
 * in his part of a diploma project
 * named DVGEditor <http://code.google.com/p/dataviewer/>
 * and  distributed under GNU GPL license.
 */
#ifndef EDITORSCENE_H
#define EDITORSCENE_H

#include <QGraphicsScene>
#include <QMap>
#include <QSet>

 class QGraphicsSceneMouseEvent;
 class QMenu;
 class QPointF;
 class QGraphicsLineItem;
 class QFont;
 class QGraphicsTextItem;
 class QColor;
 class MagicPolygon;
 class QLabel;
 class QTextStream;
 class QDomNodeList;

class EditorScene : public QGraphicsScene
{
    Q_OBJECT
public:
    enum Mode { InsertItem, InsertPolygon, InsertText, MoveItem, HandItem };

    EditorScene(QObject *parent = 0);
    EditorScene(qreal x,qreal y,qreal width,qreal height,QObject *parent = 0);
    ~EditorScene();

    inline void setContextMenu(QMenu *menu){ m_pContextMenu = menu; }
    inline void setToolContextMenu(QMenu *menu){ m_pToolContextMenu = menu; }

    //!Getters setters
    QFont font() const
        { return m_font; }
    QColor textColor() const
        { return m_textColor; }
    QBrush itemBrush() const
        { return m_itemColor; }
    QPen itemPen() const
        { return m_lineColor; }

    /*!
      Change the pen of selected elements
      */
    void setItemPen(const QPen &color);
    //!Not used yet
    void setTextColor(const QColor &color);
     /*!
      Change the brush of selected elements
      */
    void setItemBrush(const QBrush &color);
    //!Not used yet
    void setFont(const QFont &font);

    /*!
      Set the layer id for selected elements (for computer vision libs)
      */
    void setLayerId(const int layer);
    /*!
      Adds a resizinble item into scene
      */
    QGraphicsItem* addResizingItem(QGraphicsItem* item);
    /*!
      Remove item (also resibles)
      */
    void removeItem(QGraphicsItem* item);
    /*!
      renderScene into a bitmap all primitives with layer id = layer
      */
    QImage* renderScene(int layer);
    /*!
      Gets only resizing objects
      */
    QList<QGraphicsItem*> getFiltredSelectedItems();
    QList<QGraphicsItem*> getAllItems();
    QList<QGraphicsItem*> getAllPolygons();
    bool isScenePoly(QGraphicsItem* item);
    qreal getMaxZValueInScenePoly();
    void save(QDataStream* out);
    void load(QDataStream* out);
    void saveObjects(QTextStream *out);
    void loadObjects(QDomNodeList *list);
public slots:
    /*!
      Change editing mode
      */
    void setMode(Mode mode);
    /*!
      Set current primitive that will be added on MousePress with ItemIsert Mode selected
      */
    void setPrimitive(QGraphicsItem* primitive);

signals:
    void textInserted(QGraphicsTextItem *item);
    void itemSelected(QGraphicsItem *item);
signals:
    void modeChanged();
    void modeChanged(int mode);
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
    QList<QGraphicsItem*> excludeTools(QList<QGraphicsItem*> selection);
    QList<QGraphicsItem*> includeTools(QList<QGraphicsItem*> selection);
    bool isPoly(QGraphicsItem* item);
    void cleanLines();
protected slots:

    void innerSelectionChanged();
private:
    //Current mode
    Mode m_mode;
    //Flag for left button pressed
    bool leftButtonDown;
    //Current primitive
    QGraphicsItem* m_primitive;

    //Drawing polygons
    QPointF startPoint;
    QList<QGraphicsLineItem*> lines;
    QGraphicsLineItem* line;


    QFont m_font;

    QColor m_textColor;
    QBrush m_itemColor;
    QPen m_lineColor;
    int default_layer;

    QMap<QGraphicsItem*,MagicPolygon*> magicpoly;
    QSet<QGraphicsItem*> magicpolywerif;
    QSet<QGraphicsItem*> scenepolygons;

   void hideAll();
   void hideTools();
   void hideOthers(QGraphicsItem* item);
   void showFromObj(QGraphicsItem* obj);

   //-------------------------
   QMenu  *m_pContextMenu;
   QMenu  *m_pToolContextMenu;
   QRectF  m_documentRect;
   QLabel *m_pObjectLabel;
   QPen    m_linePen;
   QString m_documentName;
   QColor  m_documentColor;
   int     m_lastObjectUID;
public:
   inline void setDocumentRect(QRectF rect){ m_documentRect = rect; }
   inline QRectF documentRect(){ return m_documentRect; }
   inline void setDocumentName(const QString& name){ m_documentName = name; }
   inline QString documentName(){ return m_documentName; }
   inline void setDocumentColor(const QColor& color){ m_documentColor = color; }
   inline QColor documentColor(){ return m_documentColor; }
   inline void setObjectLabel(QLabel *label){ m_pObjectLabel = label; }
   void showObjectName(bool show, MagicPolygon *poly = 0);

   static QColor  getColorRGBA(const QString & name);
   static QString getColorStringRGBA(const QColor& color);
   //-------------------------
};

/*!
  Dumb class privding tools for editor
  to reproject
  */

class Tool
{
    public:
    Tool();
    ~Tool();

    enum ItemType{PointerItem,PolygonItem,RectItem,EllipseItem,SectorItem,DeleteItem,HandItem};
    static QGraphicsItem* createItem(ItemType type);
    static EditorScene::Mode getMode(ItemType type);

};

#endif // EDITORSCENE_H
